

<!DOCTYPE html>
<html lang="zh-CN" data-default-color-scheme=&#34;auto&#34;>



<head>
  <meta charset="UTF-8">
  <link rel="apple-touch-icon" sizes="76x76" href="/img/favicon.png">
  <link rel="icon" type="image/png" href="/img/favicon.png">
  <meta name="viewport"
        content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, shrink-to-fit=no">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  
  <meta name="theme-color" content="#2f4154">
  <meta name="description" content="">
  <meta name="author" content="caoyusang">
  <meta name="keywords" content="">
  <title>JVM垃圾回收 - caoyusang的科研日常</title>

  <link  rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.4.1/css/bootstrap.min.css" />


  <link  rel="stylesheet" href="https://cdn.staticfile.org/github-markdown-css/4.0.0/github-markdown.min.css" />
  <link  rel="stylesheet" href="/lib/hint/hint.min.css" />

  
    
    
      
      <link  rel="stylesheet" href="https://cdn.staticfile.org/highlight.js/10.0.0/styles/github-gist.min.css" />
    
  

  


<!-- 主题依赖的图标库，不要自行修改 -->

<link rel="stylesheet" href="//at.alicdn.com/t/font_1749284_ba1fz6golrf.css">



<link rel="stylesheet" href="//at.alicdn.com/t/font_1736178_kmeydafke9r.css">


<link  rel="stylesheet" href="/css/main.css" />

<!-- 自定义样式保持在最底部 -->


  <script  src="/js/utils.js" ></script>
  <script  src="/js/color-schema.js" ></script>
<meta name="generator" content="Hexo 5.2.0"></head>


<body>
  <header style="height: 70vh;">
    <nav id="navbar" class="navbar fixed-top  navbar-expand-lg navbar-dark scrolling-navbar">
  <div class="container">
    <a class="navbar-brand"
       href="/">&nbsp;<strong>caoyusang</strong>&nbsp;</a>

    <button id="navbar-toggler-btn" class="navbar-toggler" type="button" data-toggle="collapse"
            data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <div class="animated-icon"><span></span><span></span><span></span></div>
    </button>

    <!-- Collapsible content -->
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav ml-auto text-center">
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/">
                <i class="iconfont icon-home-fill"></i>
                首页
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/archives/">
                <i class="iconfont icon-archive-fill"></i>
                归档
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/categories/">
                <i class="iconfont icon-category-fill"></i>
                分类
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/tags/">
                <i class="iconfont icon-tags-fill"></i>
                标签
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/about/">
                <i class="iconfont icon-user-fill"></i>
                关于
              </a>
            </li>
          
        
        
          <li class="nav-item" id="search-btn">
            <a class="nav-link" data-toggle="modal" data-target="#modalSearch">&nbsp;<i
                class="iconfont icon-search"></i>&nbsp;</a>
          </li>
        
        
          <li class="nav-item" id="color-toggle-btn">
            <a class="nav-link" href="javascript:">&nbsp;<i
                class="iconfont icon-dark" id="color-toggle-icon"></i>&nbsp;</a>
          </li>
        
      </ul>
    </div>
  </div>
</nav>

    <div class="banner intro-2" id="background" parallax=true
         style="background: url('/img/7.jpg') no-repeat center center;
           background-size: cover;">
      <div class="full-bg-img">
        <div class="mask flex-center" style="background-color: rgba(0, 0, 0, 0.3)">
          <div class="container page-header text-center fade-in-up">
            <span class="h2" id="subtitle">
              
            </span>

            
              <div class="mt-3">
  
  
    <span class="post-meta">
      <i class="iconfont icon-date-fill" aria-hidden="true"></i>
      <time datetime="2021-05-28 19:44" pubdate>
        2021年5月28日 晚上
      </time>
    </span>
  
</div>

<div class="mt-1">
  
    
    <span class="post-meta mr-2">
      <i class="iconfont icon-chart"></i>
      2.7k 字
    </span>
  

  
    
    <span class="post-meta mr-2">
      <i class="iconfont icon-clock-fill"></i>
      
      
      35
       分钟
    </span>
  

  
  
    
      <!-- 不蒜子统计文章PV -->
      <span id="busuanzi_container_page_pv" style="display: none">
        <i class="iconfont icon-eye" aria-hidden="true"></i>
        <span id="busuanzi_value_page_pv"></span> 次
      </span>
    
  
</div>

            
          </div>

          
        </div>
      </div>
    </div>
  </header>

  <main>
    
      

<div class="container-fluid">
  <div class="row">
    <div class="d-none d-lg-block col-lg-2"></div>
    <div class="col-lg-8 nopadding-md">
      <div class="container nopadding-md" id="board-ctn">
        <div class="py-5" id="board">
          <article class="post-content mx-auto" id="post">
            <!-- SEO header -->
            <h1 style="display: none">JVM垃圾回收</h1>
            
              <p class="note note-info">
                
                  本文最后更新于：12 分钟前
                
              </p>
            
            <div class="markdown-body" id="post-body">
              <h2 id="垃圾回收-GC"><a href="#垃圾回收-GC" class="headerlink" title="垃圾回收(GC)"></a>垃圾回收(GC)</h2><h3 id="1-哪些是垃圾？"><a href="#1-哪些是垃圾？" class="headerlink" title="1.哪些是垃圾？"></a>1.哪些是垃圾？</h3><p>堆中存放了几乎所有的对象实例，在垃圾收集器对堆进行垃圾回收时，首先要确定的就是堆中对象是否存活。</p>
<p>判断对象是否存活有两种方法：引用计数法和可达性分析法。</p>
<h4 id="引用计数法"><a href="#引用计数法" class="headerlink" title="引用计数法"></a><code>引用计数法</code></h4><div class="table-container">
<table>
<thead>
<tr>
<th style="text-align:center"><strong>方法描述</strong></th>
<th style="text-align:center"><strong>给对象中<code>添加一个引用计数器</code>，每当有一个地方引用它，计数器就加 1；当引用失效，计数器就减 1；任何时候计数器为 0 的对象就是不可能再被使用的</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:center"><strong>优点</strong></td>
<td style="text-align:center"><strong>实现<code>简单</code>，效率高</strong></td>
</tr>
<tr>
<td style="text-align:center"><strong>缺点</strong></td>
<td style="text-align:center"><strong>很难解决对象之间<code>相互循环引用</code>的问题</strong></td>
</tr>
</tbody>
</table>
</div>
<h4 id="可达性分析法"><a href="#可达性分析法" class="headerlink" title="可达性分析法"></a><code>可达性分析法</code></h4><p>通过一系列的称为<code>“GC Roots”</code>的对象作为起点，从这些节点开始向下搜索，节点所走过的路径称为<code>引用链</code>，当一个对象到 GC Roots <code>没有任何引用链相连的话，则证明此对象是不可用的</code></p>
<img src="/2021/05/28/JVM%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6/image-20210526190547058.png" srcset="/img/loading.gif" class="">
<p><code>GC Roots对象集合(GC Root Set)</code>中可能包含的对象：</p>
<ul>
<li>虚拟机栈(栈帧中的<code>本地变量表</code>)中引用的对象</li>
<li>本地方法栈(<code>Native 方法</code>)中引用的对象</li>
<li>方法区中<code>类静态属性</code>引用的对象</li>
<li>方法区中<code>常量</code>引用的对象</li>
<li>所有被<code>同步锁持有</code>的对象</li>
</ul>
<h3 id="2-引用分类"><a href="#2-引用分类" class="headerlink" title="2.引用分类"></a>2.引用分类</h3><div class="table-container">
<table>
<thead>
<tr>
<th style="text-align:center">类型</th>
<th style="text-align:center">回收时间</th>
<th style="text-align:center">应用场景</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:center">强引用</td>
<td style="text-align:center">一直存活，除非GC Roots不可达</td>
<td style="text-align:center">所有程序的场景，基本对象，自定义对象等</td>
</tr>
<tr>
<td style="text-align:center">软引用</td>
<td style="text-align:center">内存不足时会被回收</td>
<td style="text-align:center">一般用在对内存非常敏感的资源上，用作缓存的场景比较多</td>
</tr>
<tr>
<td style="text-align:center">弱引用</td>
<td style="text-align:center">只能存活到下一次GC前</td>
<td style="text-align:center">生命周期很短的对象，例如ThreadLocal中的Key。</td>
</tr>
<tr>
<td style="text-align:center">虚引用</td>
<td style="text-align:center">随时会被回收</td>
<td style="text-align:center">可能被JVM团队内部用来跟踪JVM的垃圾回收活动</td>
</tr>
</tbody>
</table>
</div>
<h3 id="3-GC分类"><a href="#3-GC分类" class="headerlink" title="3.GC分类"></a>3.GC分类</h3><h4 id="Partial-GC"><a href="#Partial-GC" class="headerlink" title="Partial GC"></a><code>Partial GC</code></h4><p><code>部分收集</code>，针对堆不同年代的对象进行垃圾回收。</p>
<ul>
<li>新生代收集(Minor GC) —— 只对新生代进行垃圾收集</li>
<li>老年代收集(Major GC) —— 只对老年代进行垃圾收集</li>
<li>混合收集(Mixed GC) —— 对<code>整个新生代</code>和<code>部分老年代</code>进行垃圾收集</li>
</ul>
<h4 id="Full-GC"><a href="#Full-GC" class="headerlink" title="Full GC"></a><code>Full GC</code></h4><p><code>整堆收集</code>，收集整个Java堆和方法区。</p>
<h3 id="4-GC算法"><a href="#4-GC算法" class="headerlink" title="4.GC算法"></a>4.GC算法</h3><h4 id="标记-清除算法"><a href="#标记-清除算法" class="headerlink" title="标记-清除算法"></a><code>标记-清除算法</code></h4><img src="/2021/05/28/JVM%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6/image-20210526192952904.png" srcset="/img/loading.gif" class="">
<div class="table-container">
<table>
<thead>
<tr>
<th style="text-align:center"><strong>方法概述</strong></th>
<th style="text-align:center"><strong>先标记(垃圾判定)需要回收的对象，标记完成后，进行统一回收</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:center"><strong><code>执行效率不稳定</code></strong></td>
<td style="text-align:center"><strong>标记和清除两个过程的<code>执行效率随着需要回收的对象的数量增长而降低</code></strong></td>
</tr>
<tr>
<td style="text-align:center"><strong><code>导致内存空间碎片化</code></strong></td>
<td style="text-align:center"><strong>标记、清除后会产生大量不连续的内存碎片；这会导致<code>当需要分配较大对象的时候没办法找到足够的连续内存进行分配</code>，因此不得不提前触发另一次GC</strong></td>
</tr>
</tbody>
</table>
</div>
<h4 id="标记-复制算法"><a href="#标记-复制算法" class="headerlink" title="标记-复制算法"></a><code>标记-复制算法</code></h4><img src="/2021/05/28/JVM%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6/image-20210526193557450.png" srcset="/img/loading.gif" class="">
<div class="table-container">
<table>
<thead>
<tr>
<th style="text-align:center">方法概述</th>
<th style="text-align:center">将可用内存分为大小相同的两块，每次只使用其中一块进行内存分配，当这一块的内存用完了，进行垃圾回收后，将仍存活的对象复制到另外一块保留的内存上，再把已使用过的内存空间一次清理掉</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:center"><strong>优点</strong></td>
<td style="text-align:center"><strong>实现简单，运行高效，给对象分配内存<code>不会存在空间碎片</code>的情况</strong></td>
</tr>
<tr>
<td style="text-align:center"><strong><code>内存空间浪费严重</code></strong></td>
<td style="text-align:center"><strong>可用内存直接减半</strong></td>
</tr>
<tr>
<td style="text-align:center"><strong><code>不适合老年代GC</code></strong></td>
<td style="text-align:center"><strong>老年代对象存活时间长，GC时需要复制的对象很多，这样将<code>产生大量的内存间复制的开销</code>，相反，适合作为新生代区域的收集算法</strong></td>
</tr>
</tbody>
</table>
</div>
<h4 id="标记-整理算法"><a href="#标记-整理算法" class="headerlink" title="标记-整理算法"></a><code>标记-整理算法</code></h4><p>根据<code>老年代的特点提出的一种标记算法</code>，标记过程仍然与“标记-清除”算法一样，但后续步骤不是直接对可回收对象回收，而是<code>让所有存活的对象向一端移动，然后直接清理掉端边界以外的内存</code>。</p>
<img src="/2021/05/28/JVM%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6/image-20210526194242713.png" srcset="/img/loading.gif" class="">
<h3 id="5-GC收集器"><a href="#5-GC收集器" class="headerlink" title="5.GC收集器"></a>5.GC收集器</h3><h4 id="Serial收集器"><a href="#Serial收集器" class="headerlink" title="Serial收集器"></a>Serial收集器</h4><img src="/2021/05/28/JVM%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6/image-20210527084654888.png" srcset="/img/loading.gif" class="">
<div class="table-container">
<table>
<thead>
<tr>
<th style="text-align:center"><strong>特点</strong></th>
<th style="text-align:center"><strong>描述</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:center"><strong>最基本也是历史最悠久的垃圾收集器</strong></td>
<td style="text-align:center"><strong>-</strong></td>
</tr>
<tr>
<td style="text-align:center"><strong><code>单线程</code></strong></td>
<td style="text-align:center"><strong>只会用一个垃圾收集线程完成垃圾收集工作，在进行垃圾收集时，必须暂停其他所有的工作线程（<code>咋瓦鲁多？</code>）</strong></td>
</tr>
<tr>
<td style="text-align:center"><strong>垃圾回收策略</strong></td>
<td style="text-align:center"><strong>新生代（标记-复制）、老年代（标记-整理）</strong></td>
</tr>
<tr>
<td style="text-align:center"><strong><code>简单高效</code></strong></td>
<td style="text-align:center"><strong>没有多线程交互的开销，可以获得很高的单线程收集效率</strong></td>
</tr>
<tr>
<td style="text-align:center"><strong>适合运行在<code>Client</code>模式下的虚拟机</strong></td>
<td style="text-align:center"><strong>-</strong></td>
</tr>
</tbody>
</table>
</div>
<h4 id="ParNew收集器"><a href="#ParNew收集器" class="headerlink" title="ParNew收集器"></a>ParNew收集器</h4><img src="/2021/05/28/JVM%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6/image-20210527091529278.png" srcset="/img/loading.gif" class="">
<div class="table-container">
<table>
<thead>
<tr>
<th style="text-align:center"><strong>特点</strong></th>
<th style="text-align:center"><strong>描述</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:center"><strong>Serial收集器的<code>多线程版本</code></strong></td>
<td style="text-align:center"><strong>除了使用多线程进行垃圾收集外，其余行为（控制参数、收集算法、回收策略等等）和 Serial 收集器完全一样</strong></td>
</tr>
<tr>
<td style="text-align:center"><strong><code>多线程</code></strong></td>
<td style="text-align:center"><strong>默认开启的收集线程数目和处理器的核心数目相同</strong></td>
</tr>
<tr>
<td style="text-align:center"><strong>垃圾回收策略</strong></td>
<td style="text-align:center"><strong>新生代（标记-复制）、老年代（标记-整理）</strong></td>
</tr>
<tr>
<td style="text-align:center"><strong>适合运行在<code>server</code>模式下的虚拟机</strong></td>
<td style="text-align:center"><strong>-</strong></td>
</tr>
</tbody>
</table>
</div>
<h5 id="收集器中的并发vs并行"><a href="#收集器中的并发vs并行" class="headerlink" title="收集器中的并发vs并行"></a><code>收集器中的并发vs并行</code></h5><ul>
<li>并行（Parallel） —— 描述的是多条垃圾收集器线程之间的关系，说明同一时间有多条这样的线程在协同工作，通常默认此时用户线程处于等待状态。</li>
<li>并发（Concurrent）—— 描述的是垃圾收集器线程与用户线程之间的关系，说明同一时间垃圾收集器线程和用户线程都在运行。由于用户线程未被冻结，所以程序仍然能响应服务请求，但是这时由于垃圾收集器线程占用了一部分系统资源，此时应用程序处理的吞吐量将受一定的影响。</li>
</ul>
<h4 id="Parallel-Scavenge收集器"><a href="#Parallel-Scavenge收集器" class="headerlink" title="Parallel Scavenge收集器"></a><code>Parallel Scavenge收集器</code></h4><p>使用标记-复制算法的多线程收集器，看上去几乎和 ParNew 一样。只不过Parallel Scavenge 收集器关注点是吞吐量即如何高效率地利用CPU。</p>
<img src="/2021/05/28/JVM%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6/image-20210527090739629.png" srcset="/img/loading.gif" class="">
<div class="table-container">
<table>
<thead>
<tr>
<th style="text-align:center"><strong>特点</strong></th>
<th style="text-align:center"><strong>描述</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:center"><strong>目标在于达到一个<code>可控的服务吞吐量</code></strong></td>
<td style="text-align:center"><strong>吞吐量就是CPU用于运行用户代码的时间与CPU总耗时的比值</strong></td>
</tr>
<tr>
<td style="text-align:center"><strong><code>控制吞吐量的参数</code></strong></td>
<td style="text-align:center"><strong>-XX: MaxGCPauseMillis(最大垃圾收集停顿时间)，-XX: GCTimeRatio(直接设置吞吐量大小)</strong></td>
</tr>
<tr>
<td style="text-align:center"><strong>多线程</strong></td>
<td style="text-align:center"><strong>-</strong></td>
</tr>
<tr>
<td style="text-align:center"><strong>垃圾回收策略</strong></td>
<td style="text-align:center"><strong>新生代（标记-复制）、老年代（标记-整理）</strong></td>
</tr>
</tbody>
</table>
</div>
<h4 id="Serial-Old收集器"><a href="#Serial-Old收集器" class="headerlink" title="Serial Old收集器"></a><strong>Serial Old收集器</strong></h4><img src="/2021/05/28/JVM%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6/image-20210527084654888.png" srcset="/img/loading.gif" class="">
<p><strong>Serial 收集器的<code>老年代版本</code>，它同样是一个<code>单线程</code>收集器。它主要有两大用途：一种用途是在 JDK1.5 以及以前的版本中与 Parallel Scavenge 收集器搭配使用，另一种用途是作为 CMS 收集器的后备方案。</strong></p>
<h4 id="Parallel-Old收集器"><a href="#Parallel-Old收集器" class="headerlink" title="Parallel Old收集器"></a><strong>Parallel Old收集器</strong></h4><img src="/2021/05/28/JVM%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6/image-20210527091641274.png" srcset="/img/loading.gif" class="">
<p><strong>Parallel Scavenge 收集器的<code>老年代版本</code>。使用<code>多线程和“标记-整理”</code>算法。在注重吞吐量以及 CPU 资源的场合，都可以优先考虑Parallel Scavenge 收集器和Parallel Old收集器的组合。</strong></p>
<h4 id="CMS收集器"><a href="#CMS收集器" class="headerlink" title="CMS收集器"></a><strong><code>CMS收集器</code></strong></h4><p>Concurrent <code>Mark Sweep</code>收集器以<code>获取最短回收停顿时间</code>为目标。从名字上就能看出来，CMS收集器是基于<code>标记-清除</code>算法实现的，运行过程主要包括以下四个步骤：</p>
<ol>
<li>初始标记 —— 标记GC Roots能直接关联到的对象，速度快，需要”咋瓦鲁多“</li>
<li>并发标记 —— 从GC Roots的直接关联对象开始遍历整个对象图（进行可达性分析），速度慢，不需要停顿用户线程，可以和垃圾收集线程并发运行</li>
<li>重新标记 —— 修正在并发标记期间因用户程序继续运作导致标记产生变动的那一部分对象的标记记录，速度快，耗时略比初始标记长一些</li>
<li>并发清除 —— 清理标记阶段判断已经死亡的对象，由于不用移动存活对象，因此这个阶段也可以和用户线程并发执行</li>
</ol>
<img src="/2021/05/28/JVM%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6/image-20210527094248179.png" srcset="/img/loading.gif" class="">
<div class="table-container">
<table>
<thead>
<tr>
<th style="text-align:center">对比</th>
<th style="text-align:center">初始标记</th>
<th style="text-align:center">并发标记</th>
<th style="text-align:center">重新标记</th>
<th style="text-align:center">并发清除</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:center">过程</td>
<td style="text-align:center">标记GC Roots能<code>直接关联到的对象</code></td>
<td style="text-align:center"><code>从GC Roots的直接关联对象开始遍历整个对象图</code></td>
<td style="text-align:center"><code>修正</code>在并发标记期间因用户程序继续运作导致标记产生变动的那一部分对象的标记记录</td>
<td style="text-align:center">清理标记阶段判断已经死亡的对象</td>
</tr>
<tr>
<td style="text-align:center">速度</td>
<td style="text-align:center">快</td>
<td style="text-align:center">慢</td>
<td style="text-align:center">快，略比初始标记时间长</td>
<td style="text-align:center">-</td>
</tr>
<tr>
<td style="text-align:center"><code>能否与用户线程并发执行</code></td>
<td style="text-align:center">×</td>
<td style="text-align:center">√</td>
<td style="text-align:center">×</td>
<td style="text-align:center">√</td>
</tr>
</tbody>
</table>
</div>
<h5 id="CMS收集器的优缺点"><a href="#CMS收集器的优缺点" class="headerlink" title="CMS收集器的优缺点"></a><code>CMS收集器的优缺点</code></h5><p><code>优点</code></p>
<ul>
<li>并发收集、低停顿（服务响应速度快），可以给用户带来良好的交互体验</li>
</ul>
<p><code>缺点</code></p>
<ul>
<li>对处理器资源十分敏感。CMS<code>默认启动的回收线程数是(CPU核心线程数+3)/4</code>，当CPU的核心数大于等于4时，使用CMS收集器进行垃圾回收，垃圾回收线程只占用不超过四分之一的CPU运算资源，而当CPU核心数小于4时，CPU能提供的负载本来就有限，还要分出将近一半的运算能力去执行垃圾收集器线程，则会就会导致用户程序的执行速度忽然大幅降低。</li>
<li>无法处理“浮动垃圾”。并发清理阶段，用户线程仍在继续运行，会不断地产生垃圾对象，而这一部分垃圾对象出现在标记过程结束之后，CMS无法在当次收集过程中处理它们，只能留待下一次垃圾收集再进行处理，这部分垃圾就是“浮动垃圾”。</li>
<li>产生大量空间碎片。因为CMS收集器在垃圾清除阶段使用的是“标记-清除”算法。</li>
</ul>
<h4 id="G1收集器"><a href="#G1收集器" class="headerlink" title="G1收集器"></a><code>G1收集器</code></h4><p>Garbage First收集器（G1）是一款<code>面向服务端应用</code>的垃圾收集器，JDK9发布之后，G1收集器宣告取代Parallel Scavenge+Parallel Old组合，成为<code>服务端模式下的默认垃圾收集器</code>。G1收集器主要针对配备多颗处理器及大容量内存的机器.，能够以极高概率满足GC停顿时间要求的同时，同时还具备高吞吐量性能特征。</p>
<p>在G1收集器出现之前，所有的垃圾收集器（包括CMS）的目标范围要么是整个新生代（Minor GC），要么是整个老年代（Major GC），要么是整个Java堆（Full GC）。而G1跳出了这个樊笼，可以面向堆内存的任何部分组成回收集（Cset）进行回收，回收的衡量标准不再是垃圾对象属于哪个分代，而变成了哪块内存中存放的垃圾数目最多，回收收益最大，这就是<code>G1的Mixed GC模式</code>。</p>
<img src="/2021/05/28/JVM%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6/image-20210527101604507.png" srcset="/img/loading.gif" class="">
<h5 id="G1基于Region的堆内存布局"><a href="#G1基于Region的堆内存布局" class="headerlink" title="G1基于Region的堆内存布局"></a><code>G1基于Region的堆内存布局</code></h5><p><code>G1之前的JVM内存模型</code></p>
<p>
            </div>
            <hr>
            <div>
              <div class="post-metas mb-3">
                
                  <div class="post-meta mr-3">
                    <i class="iconfont icon-category"></i>
                    
                      <a class="hover-with-bg" href="/categories/Java/">Java</a>
                    
                  </div>
                
                
                  <div class="post-meta">
                    <i class="iconfont icon-tags"></i>
                    
                      <a class="hover-with-bg" href="/tags/JVM/">JVM</a>
                    
                  </div>
                
              </div>
              
                <p class="note note-warning">本博客所有文章除特别声明外，均采用 <a target="_blank" href="https://creativecommons.org/licenses/by-sa/4.0/deed.zh" rel="nofollow noopener noopener">CC BY-SA 4.0 协议</a> ，转载请注明出处！</p>
              
              
                <div class="post-prevnext row">
                  <article class="post-prev col-6">
                    
                    
                  </article>
                  <article class="post-next col-6">
                    
                    
                      <a href="/2021/05/28/%E7%B1%BB%E5%8A%A0%E8%BD%BD%E6%9C%BA%E5%88%B6/">
                        <span class="hidden-mobile">类加载机制</span>
                        <span class="visible-mobile">下一篇</span>
                        <i class="iconfont icon-arrowright"></i>
                      </a>
                    
                  </article>
                </div>
              
            </div>

            
          </article>
        </div>
      </div>
    </div>
    
      <div class="d-none d-lg-block col-lg-2 toc-container" id="toc-ctn">
        <div id="toc">
  <p class="toc-header"><i class="iconfont icon-list"></i>&nbsp;目录</p>
  <div id="tocbot"></div>
</div>

      </div>
    
  </div>
</div>

<!-- Custom -->


    
  </main>

  
    <a id="scroll-top-button" href="#" role="button">
      <i class="iconfont icon-arrowup" aria-hidden="true"></i>
    </a>
  

  
    <div class="modal fade" id="modalSearch" tabindex="-1" role="dialog" aria-labelledby="ModalLabel"
     aria-hidden="true">
  <div class="modal-dialog modal-dialog-scrollable modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header text-center">
        <h4 class="modal-title w-100 font-weight-bold">搜索</h4>
        <button type="button" id="local-search-close" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body mx-3">
        <div class="md-form mb-5">
          <input type="text" id="local-search-input" class="form-control validate">
          <label data-error="x" data-success="v"
                 for="local-search-input">关键词</label>
        </div>
        <div class="list-group" id="local-search-result"></div>
      </div>
    </div>
  </div>
</div>
  

  

  <footer class="text-center mt-5 py-3">
  <div class="footer-content">
     <a href="https://hexo.io" target="_blank" rel="nofollow noopener"><span>Hexo</span></a> <i class="iconfont icon-love"></i> <a href="https://github.com/fluid-dev/hexo-theme-fluid" target="_blank" rel="nofollow noopener"><span>Fluid</span></a> 
  </div>
  

  

  
</footer>

<!-- SCRIPTS -->
<script  src="https://cdn.staticfile.org/jquery/3.4.1/jquery.min.js" ></script>
<script  src="https://cdn.staticfile.org/twitter-bootstrap/4.4.1/js/bootstrap.min.js" ></script>
<script  src="/js/debouncer.js" ></script>
<script  src="/js/main.js" ></script>

<!-- Plugins -->


  
    <script  src="/js/lazyload.js" ></script>
  



  



  <script defer src="https://cdn.staticfile.org/clipboard.js/2.0.6/clipboard.min.js" ></script>
  <script  src="/js/clipboard-use.js" ></script>



  <script defer src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js" ></script>





  <script  src="https://cdn.staticfile.org/tocbot/4.11.1/tocbot.min.js" ></script>
  <script>
    $(document).ready(function () {
      var boardCtn = $('#board-ctn');
      var boardTop = boardCtn.offset().top;

      tocbot.init({
        tocSelector: '#tocbot',
        contentSelector: '#post-body',
        headingSelector: 'h1,h2,h3,h4,h5,h6',
        linkClass: 'tocbot-link',
        activeLinkClass: 'tocbot-active-link',
        listClass: 'tocbot-list',
        isCollapsedClass: 'tocbot-is-collapsed',
        collapsibleClass: 'tocbot-is-collapsible',
        collapseDepth: 0,
        scrollSmooth: true,
        headingsOffset: -boardTop
      });
      if ($('.toc-list-item').length > 0) {
        $('#toc').css('visibility', 'visible');
      }
    });
  </script>



  <script  src="https://cdn.staticfile.org/typed.js/2.0.11/typed.min.js" ></script>
  <script>
    var typed = new Typed('#subtitle', {
      strings: [
        '  ',
        "JVM垃圾回收&nbsp;",
      ],
      cursorChar: "_",
      typeSpeed: 70,
      loop: false,
    });
    typed.stop();
    $(document).ready(function () {
      $(".typed-cursor").addClass("h2");
      typed.start();
    });
  </script>



  <script  src="https://cdn.staticfile.org/anchor-js/4.2.2/anchor.min.js" ></script>
  <script>
    anchors.options = {
      placement: "right",
      visible: "hover",
      
    };
    var el = "h1,h2,h3,h4,h5,h6".split(",");
    var res = [];
    for (item of el) {
      res.push(".markdown-body > " + item)
    }
    anchors.add(res.join(", "))
  </script>



  <script  src="/js/local-search.js" ></script>
  <script>
    var path = "/local-search.xml";
    var inputArea = document.querySelector("#local-search-input");
    inputArea.onclick = function () {
      searchFunc(path, 'local-search-input', 'local-search-result');
      this.onclick = null
    }
  </script>



  <script  src="https://cdn.staticfile.org/fancybox/3.5.7/jquery.fancybox.min.js" ></script>
  <link  rel="stylesheet" href="https://cdn.staticfile.org/fancybox/3.5.7/jquery.fancybox.min.css" />

  <script>
    $('#post img:not(.no-zoom img, img[no-zoom]), img[zoom]').each(
      function () {
        var element = document.createElement('a');
        $(element).attr('data-fancybox', 'images');
        $(element).attr('href', $(this).attr('src'));
        $(this).wrap(element);
      }
    );
  </script>





  

  
    <!-- MathJax -->
    <script>
      MathJax = {
        tex: {
          inlineMath: [['$', '$'], ['\\(', '\\)']]
        },
        options: {
          renderActions: {
            findScript: [10, doc => {
              document.querySelectorAll('script[type^="math/tex"]').forEach(node => {
                const display = !!node.type.match(/; *mode=display/);
                const math = new doc.options.MathItem(node.textContent, doc.inputJax[0], display);
                const text = document.createTextNode('');
                node.parentNode.replaceChild(text, node);
                math.start = { node: text, delim: '', n: 0 };
                math.end = { node: text, delim: '', n: 0 };
                doc.math.push(math);
              });
            }, '', false],
            insertedScript: [200, () => {
              document.querySelectorAll('mjx-container').forEach(node => {
                let target = node.parentNode;
                if (target.nodeName.toLowerCase() === 'li') {
                  target.parentNode.classList.add('has-jax');
                }
              });
            }, '', false]
          }
        }
      };
    </script>

    <script async src="https://cdn.staticfile.org/mathjax/3.0.5/es5/tex-svg.js" ></script>

  











</body>
</html>
